/* coding: UTF-8 */
/*-----------------------------------------------------------------------
|                            FILE DESCRIPTION                           |
-----------------------------------------------------------------------*/
/*----------------------------------------------------------------------
  - File name     : TimeWheel.h
  - Author        : liuzhihua
  - Update date   : 2023.4.2
  -	Brief         : time wheel for c
  - Version       : v1.0
-----------------------------------------------------------------------*/
/*-----------------------------------------------------------------------
|                               UPDATE NOTE                             |
-----------------------------------------------------------------------*/
/**
  * Update note:
  * ------------   ---------------   ----------------------------------
  *     Date            Author                      Note
  * ------------   ---------------   ----------------------------------
  *  2023.04.02       liuzhihua                  Create file          
***/

#ifndef TIMEWHEEL_H_
#define TIMEWHEEL_H_

#ifdef  __cplusplus
    extern "C" {
#endif
/*-----------------------------------------------------------------------
|                                NCLUDES                                |
-----------------------------------------------------------------------*/
#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
#include "list.h"

/*-----------------------------------------------------------------------
|                                DEFINES                                |
-----------------------------------------------------------------------*/
#define twUSE_STATIC_INLINE static inline
#define twUSE_INLINE inline
#define twUSE_INLINE_EX //inline
#define twAssert(x) assert(x)
#define twMalloc(x) malloc(x)
#define twFree_     free
#define twFree(x)   twFree_(x)
//2^32ms => 1193h => 49day
typedef uint32_t twTick_t;
typedef struct TimeWheelUnit_Structure twu_t;
typedef struct timeWheelBase_Structure twb_t;
typedef struct timeWheelTask_Structure twt_t;
typedef uint32_t twtID_t;

struct TimeWheelUnit_Structure 
{
  uint32_t tick;
  uint32_t size;
  uint32_t mask;
  uint32_t offset;
  list_t *list[];
};

struct timeWheelBase_Structure
{
  uint16_t frequence;
  uint16_t bitSize;
  uint64_t tick;
  uint32_t level;
  twt_t *currentTask;
  twu_t *twu[];
};

struct timeWheelTask_Structure
{
  twtID_t id;
  twTick_t expire;
  void *param;
  uint32_t (*function)(void *);
};

typedef enum twStatusTypedef{
  TW_OK = 0U,
  TW_MALLOC_FAILURE,
  TW_PARAM_ERROR,
  TW_NOT_FIND
}twStatus;

/**
 * @brief tick to time(ms)
 */
#define tw_tick2ms(_ptwb_, tick)\
    (tick * (1000.0f / (_ptwb_)->frequence))
/**
 * @brief time(ms) to tick
 */
#define tw_ms2tick(_ptwb_, time)\
    (time / 1000.0f * (_ptwb_)->frequence)

/*-----------------------------------------------------------------------
|                                  API                                  |
-----------------------------------------------------------------------*/
/* time wheel operate */

twb_t *tw_create_twb(uint32_t levelMax, uint8_t* levelx, uint16_t TickFrequence);
void tw_run(twb_t* ptwb);
uint64_t tw_get_tick(twb_t *ptwb);
uint64_t tw_get_time(twb_t *ptwb);
void tw_destroy_twb(twb_t **pptwb);


/* task operate */

twStatus tw_task_create(twb_t *ptwb, twTick_t ticktime, uint32_t (*function)(void*), void *param, twtID_t id);
twUSE_INLINE_EX void tw_task_set_param(twt_t *ptwt, void *param);
void tw_task_set_param_internal(twb_t *ptwb, void* param);
twStatus tw_task_set_param_id(twb_t *ptwb, twtID_t id, void* param);
twt_t *tw_task_find_id(twb_t* ptwb, twtID_t id);
void tw_task_destroy_function(twb_t *ptwb, uint32_t (*function)(void*));
void tw_task_destroy_id(twb_t *ptwb, twtID_t id);


#ifdef __cplusplus
	}
#endif
#endif
